import { MODEL_NAME } from '../../constants/model-names';
import { EVENTS, type IEventBus } from '../../events';
import type { SceneModel } from '../../model';
import { REWARD_SOURCE_TYPE } from '../../model/reward/type';
import { BaseSystem } from '../base';
import type { PlayerStateSystem } from '../player-state';

export class SceneSystem extends BaseSystem {
  private bus: IEventBus;
  private playerStateSystem: PlayerStateSystem;

  constructor(bus: IEventBus, playerStateSystem: PlayerStateSystem) {
    super();
    this.bus = bus;
    this.playerStateSystem = playerStateSystem;

    this.bus.on(EVENTS.SCENE_CHANGE, (sceneId: string) => {
      const sceneModel = this.playerStateSystem.getModel<SceneModel>(
        MODEL_NAME.SCENE
      );
      sceneModel.changeScene(sceneId);
    });

    this.bus.on(EVENTS.SCENE_EXPLORE_START, () => {
      const sceneModel = this.playerStateSystem.getModel<SceneModel>(
        MODEL_NAME.SCENE
      );
      sceneModel.startExplore();
    });

    this.bus.on(EVENTS.SCENE_AUTO_EXPLORE_START, () => {
      const sceneModel = this.playerStateSystem.getModel<SceneModel>(
        MODEL_NAME.SCENE
      );
      sceneModel.startAutoExplore();
    });

    this.bus.on(EVENTS.SCENE_TRIGGER_MANUAL_ENCOUNTER, () => {
      const sceneModel = this.playerStateSystem.getModel<SceneModel>(
        MODEL_NAME.SCENE
      );
      sceneModel.triggerManualEncounter();
    });

    this.bus.on(EVENTS.REWARD_ISSUE_COMPLETED, (sourceType) => {
      if (sourceType !== REWARD_SOURCE_TYPE.BATTLE) return;
      const sceneModel = this.playerStateSystem.getModel<SceneModel>(
        MODEL_NAME.SCENE
      );
      if (!sceneModel) return;
      if (sceneModel.getIsAutoExplore()) {
        sceneModel.startExplore();
      }
    });

    this.bus.on(EVENTS.SCENE_STOP_EXPLORE, () => {
      const sceneModel = this.playerStateSystem.getModel<SceneModel>(
        MODEL_NAME.SCENE
      );
      sceneModel.stopExplore();
    });
  }

  public update(dt: number): void {
    const sceneModel = this.playerStateSystem.getModel<SceneModel>(
      MODEL_NAME.SCENE
    );
    sceneModel.updateExploredTime(dt);
  }
}
